// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InterpolatorTest.cs" company="Microsoft Corporation">
// The MIT License (MIT)
// 
// Copyright (c) 2014, Microsoft Corporation
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Test.Robotics.Numerics
{
    using System;

    using Microsoft.Robotics.Algorithms;
    using Microsoft.Robotics.Numerics;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Unit tests for the Interpolator class
    /// </summary>
    [TestClass]
    public class InterpolatorTest
    {
        /// <summary>
        /// Test the interpolation normal case
        /// </summary>
        [Priority(0)]
        [TestMethod]
        [TestCategory("Unit")]
        public void InterpolateValues()
        {
            long startTime = 10;
            long endTime = 20;
            long[] desiredTimes = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            double start = 0;
            double end = 100;
            double[] expected = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };            
            for (int i = 0; i < desiredTimes.Length; ++i)
            {
                double interpolated = Interpolator.LinearInterpolate(startTime, endTime, desiredTimes[i], start, end);
                Assert.AreEqual(expected[i], interpolated, MathConstants.ErrorEpsilon);
            }
        }        

        /// <summary>
        /// Test the interpolation when end time is less than or equal to start time.
        /// </summary>
        [Priority(0)]
        [TestMethod]
        [TestCategory("Unit")]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void InterpolateValuesInvalidEndTime()
        {
            long startTime = 10;
            long endTime = startTime;
            long[] desiredTimes = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            double start = 0;
            double end = 100;
            double[] expected = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };            
            for (int i = 0; i < desiredTimes.Length; ++i)
            {
                double interpolated = Interpolator.LinearInterpolate(startTime, endTime, desiredTimes[i], start, end);
                Assert.AreEqual(expected[i], interpolated, MathConstants.ErrorEpsilon);
            }
        }

        /// <summary>
        /// Test the interpolation when desired time is before start time
        /// </summary>
        [Priority(0)]
        [TestMethod]
        [TestCategory("Unit")]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void InterpolateValuesInvalidDesiredTimeBeforeStart()
        {
            long startTime = 10;
            long endTime = 10;
            long desiredTime = startTime - 1;
            double start = 0;
            double end = 100;                        
            double interpolated = Interpolator.LinearInterpolate(startTime, endTime, desiredTime, start, end);                
        }

        /// <summary>
        /// Test the interpolation when desired time is after end time
        /// </summary>
        [Priority(0)]
        [TestMethod]
        [TestCategory("Unit")]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void InterpolateValuesInvalidDesiredTimeAfterEnd()
        {
            long startTime = 10;
            long endTime = 10;
            long desiredTime = endTime + 1;
            double start = 0;
            double end = 100;            
            double interpolated = Interpolator.LinearInterpolate(startTime, endTime, desiredTime, start, end);                
        }
    }
}
